package cn.lecosa.es;

import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;

import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;

import com.alibaba.fastjson.JSONObject;

public class ElasticSearchUtil {

	private static TransportClient client;

	public ElasticSearchUtil() {
		this.client = EsClient.eSClient(); // 使用上面创建好的客户端添加到类中。
	}

	// 创建索引，并给索引某些字段指定iK分词，以后向该索引中查询时，就会用ik分词。
	public void createIndex() throws IOException {
		// 创建映射
		XContentBuilder mapping = XContentFactory.jsonBuilder().startObject()
				.startObject("properties").startObject("title1")
				.field("type", "text")
				.field("analyzer", "ik_smart")
				.endObject()
				// 该字段添加的内容，查询时将会使用ik_smart分词
				.startObject("content1").field("type", "text")
				.field("analyzer", "ik_max_word").endObject().endObject()
				.endObject();

		// index：索引名 type：类型名（可以自己定义）
		PutMappingRequest putmap = Requests.putMappingRequest("index1")
				.type("type1").source(mapping);
		// 创建索引
		client.admin().indices().prepareCreate("index1").execute().actionGet();
		// 为索引添加映射
		PutMappingResponse actionGet = client.admin().indices()
				.putMapping(putmap).actionGet();
	}

	public void createIndex1() throws IOException {
		// 添加数据
		IndexResponse response = client
				.prepareIndex("guoyuwen", "bigstudent", "1") // 索引，类型，id
				.setSource(
						jsonBuilder().startObject().field("name", "wenwen")
								// 字段，值
								.field("xiongwei", "38G").field("weight", 200)
								.endObject()).get();
	}

	public void updateByClient() throws IOException, ExecutionException,
			InterruptedException {
		// 每次添加id应该不同，相当于数据表中的主键，相同 的话将会进行覆盖
		UpdateResponse response = client
				.update(new UpdateRequest("index1", "type1", "1")
						.doc(XContentFactory.jsonBuilder().startObject()
								.field("title", "中华人民共和国国歌,国歌是最好听的歌")
								.field("content", "中华人民共和国国歌,国歌是最好听的歌111")
								.endObject())).get();
	}

	// 向 索引中再添加一条数据
	public void createIndex2() throws IOException {
		IndexResponse response = client
				.prepareIndex("index1", "type1", "2")
				.setSource(
						jsonBuilder().startObject()
								.field("title", "中华民族是伟大的民族")
								.field("content", "中华民族是伟大的民族").endObject())
				.get();
	}

	// 只有一条数据，因为对title 使用的是 粗粒度分词
	public void search() {
		SearchResponse response1 = client.prepareSearch("index1", "index")
				// 指定多个索引
				.setTypes("type1", "type")
				// 指定类型
				.setSearchType(SearchType.QUERY_THEN_FETCH)
				.setQuery(QueryBuilders.matchQuery("title", "中华人民共和国国歌")) // Query
				// .setPostFilter(QueryBuilders.rangeQuery("age").from(12).to(18))
				// // Filter
				.setFrom(0).setSize(60).setExplain(true).get();
		long totalHits1 = response1.getHits().totalHits; // 命中个数
		System.out.println(totalHits1);

		SearchResponse response2 = client.prepareSearch("index1", "index")
				// 指定多个索引
				.setTypes("type1", "type")
				// 指定类型
				.setSearchType(SearchType.QUERY_THEN_FETCH)
				.setQuery(QueryBuilders.matchQuery("content", "中华人民共和国国歌")) // Query
				// .setPostFilter(QueryBuilders.rangeQuery("age").from(12).to(18))
				// // Filter
				.setFrom(0).setSize(60).setExplain(true).get();
		long totalHits2 = response2.getHits().totalHits; // 命中个数
		System.out.println(totalHits2);
	}

	public void get() {
		GetResponse response = client.prepareGet("index1", "type1", "1").get();
		Map<String, Object> source = response.getSource();
		Set<String> strings = source.keySet();
		Iterator<String> iterator = strings.iterator();
		while (iterator.hasNext()) {
			System.out.println(source.get(iterator.next()));
		}
	}

	// 10 将搜索得到的数据以json数据形式返回

	/**
	 * 商品搜索
	 */
	public JSONObject productSearch() {
		SearchResponse response1 = client.prepareSearch("people", "index1")
				// 指定多个索引
				.setTypes("man", "type1")
				// 指定类型
				.setSearchType(SearchType.QUERY_THEN_FETCH)
				.setQuery(QueryBuilders.matchQuery("title", "中华人民共和国国歌")) // Query
				.setFrom(0).setSize(60).setExplain(true).get();

		SearchHit[] searchHits = response1.getHits().getHits();// 命中个数

		JSONObject jsonObject = new JSONObject();
		for (int i = 0; i < searchHits.length; i++) {

			String sourceAsString = searchHits[i].getSourceAsString();
			jsonObject.put(i + "", sourceAsString);

		}
		System.out.println(jsonObject);
		return jsonObject;
	}

	public static void main(String[] args) throws IOException,
			ExecutionException, InterruptedException {
		// new ElasticSearchUtil().createIndex1();
		// new ElasticSearchUtil().updateByClient();
		// new ElasticSearchUtil().createIndex2();
		// new ElasticSearchUtil().search();
		// new ElasticSearchUtil().get();

		new ElasticSearchUtil().testWildCardQuery();

	}

	public void testWildCardQuery() {
		QueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "1");
		QueryBuilder qb=QueryBuilders.boolQuery().
				must(QueryBuilders.termQuery("name","1111"))
//				must(QueryBuilders.termQuery("age",30)) 
				;
		
		QueryBuilder qb1 = QueryBuilders.wildcardQuery("title", "s*");
		SearchResponse response1 = client.prepareSearch("wantu_notice_info")
				// 指定多个索引
				.setTypes("doc" )
				// 指定类型
//				.setSearchType(SearchType.QUERY_THEN_FETCH)
				.setQuery( qb1) // Query
				// .setPostFilter(QueryBuilders.rangeQuery("age").from(12).to(18))
				// // Filter
			.get();
		SearchHit[] searchHits = response1.getHits().getHits();// 命中个数

		for (int i = 0; i < searchHits.length; i++) {
			String  sourceAsString= searchHits[i].getSourceAsString();
//			jsonObject.put(i + "", sourceAsString);
			System.out.println(sourceAsString);
		}
	}
}